package main

import (
	"bytes"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"log"
	"net"
	"net/http"
	"sync"
	"time"

	"github.com/BurntSushi/toml"
)

type Config struct {
	Servers []ServerConfig `toml:"Servers"`
}

type ServerConfig struct {
	Address        string `toml:"address"`
	MachineIDs     []int  `toml:"machine_ids"`
	SendInterval   string `toml:"send_interval"`
	UploadInterval int    `toml:"upload_interval"` // 上排值不变时的上传间隔次数
}

type HttpRequestData struct {
	Datetime    string `json:"datatime"`
	Devicename  string `json:"devicename"`
	Factorname  string `json:"factorname"`
	Factorvalue string `json:"factorvalue"`
	Timestamp   int64  `json:"timestamp"`
	SourceCode  string `json:"sourcecode"`
}

// 用于记录每个机器编号的上排值及其连续不变的次数
type MachineState struct {
	LastUpperValue int64 // 上一次的上排值
	UnchangedCount int   // 连续不变的次数
	IsFirstRun     bool  // 是否是第一次运行
}

var (
	machineStates = make(map[int64]*MachineState) // 机器编号 -> 状态
	stateMutex    = &sync.Mutex{}                 // 用于保护machineStates的互斥锁
)

func main() {
	var config Config
	if _, err := toml.DecodeFile("config.toml", &config); err != nil {
		log.Fatalf("Error reading config file: %v", err)
	}

	var wg sync.WaitGroup
	
	// 为每个服务器配置启动一个goroutine
	for _, serverConfig := range config.Servers {
		wg.Add(1)
		go func(cfg ServerConfig) {
			defer wg.Done()
			handleServer(cfg)
		}(serverConfig)
	}
	
	wg.Wait()
}

// 处理单个服务器连接
func handleServer(config ServerConfig) {
	// 连接到TCP服务器
	conn, err := net.Dial("tcp", config.Address)
	if err != nil {
		log.Fatalf("Error connecting to server %s: %v", config.Address, err)
	}
	defer conn.Close()

	fmt.Printf("Connected to server at %s\n", config.Address)

	buffer := make([]byte, 1024)
	for {
		// 读取数据
		n, err := conn.Read(buffer)
		if err != nil {
			log.Printf("Error reading from server %s: %v", config.Address, err)
			// 尝试重新连接
			time.Sleep(5 * time.Second)
			conn, err = net.Dial("tcp", config.Address)
			if err != nil {
				log.Printf("Failed to reconnect to server %s: %v", config.Address, err)
				time.Sleep(5 * time.Second)
				continue
			}
			fmt.Printf("Reconnected to server at %s\n", config.Address)
			continue
		}

		// 将数据转换为16进制字符串
		hexStr := hex.EncodeToString(buffer[:n])
		fmt.Printf("Received data from %s in hex: %s\n", config.Address, hexStr)

		// 解析数据
		if len(hexStr) >= 34 { // 确保数据长度足够
			// 提取机器编号（第13-14个字符）
			machineIDHex := hexStr[12:14]
			machineID := hexToDec(machineIDHex)

			// 检查机器ID是否在当前服务器的配置中
			if !containsInt(config.MachineIDs, int(machineID)) {
				fmt.Printf("Machine ID %d not in configuration for server %s, skipping\n", machineID, config.Address)
				continue
			}

			// 提取上排值（第19-26个字符）
			upperValueHex := hexStr[18:26]
			upperValue := hexToDec(upperValueHex)

			// 提取下排值（第27-34个字符）
			lowerValueHex := hexStr[26:34]
			lowerValue := hexToDec(lowerValueHex)

			fmt.Printf("Server %s - Machine ID: %d, Upper Value: %d, Lower Value: %d\n", 
				config.Address, machineID, upperValue, lowerValue)

			// 使用互斥锁保护共享状态
			stateMutex.Lock()
			
			// 检查上排值是否变化
			state, exists := machineStates[machineID]
			if !exists {
				// 如果机器编号不存在于状态映射中，初始化状态
				state = &MachineState{
					LastUpperValue: upperValue,
					UnchangedCount: 0,
					IsFirstRun:     true, // 标记为第一次运行
				}
				machineStates[machineID] = state
			}

			if upperValue == state.LastUpperValue {
				// 如果上排值未变化，增加连续不变次数
				state.UnchangedCount++
			} else {
				// 如果上排值变化，重置连续不变次数
				state.LastUpperValue = upperValue
				state.UnchangedCount = 0
			}

			// 如果是第一次运行，或者上排值变化，或者达到上传间隔次数，则推送数据
			shouldPush := state.IsFirstRun || upperValue != state.LastUpperValue || 
				state.UnchangedCount%config.UploadInterval == 0
			
			// 如果是第一次运行，标记为已运行
			if state.IsFirstRun {
				state.IsFirstRun = false
			}
			
			stateMutex.Unlock()

			if shouldPush {
				// 准备HTTP请求数据
				now := time.Now()
				requestData := []HttpRequestData{
					{
						Datetime:    now.Format("2006-01-02 15:04:05.000"),
						Devicename:  fmt.Sprintf("%d", machineID),
						Factorname:  "上排值",
						Factorvalue: fmt.Sprintf("%d", upperValue),
						Timestamp:   now.UnixMilli(),
						SourceCode:  hexStr,
					},
					//{
					//	Datetime:    now.Format("2006-01-02 15:04:05.000"),
					//	Devicename:  fmt.Sprintf("%d", machineID),
					//	Factorname:  "下排值",
					//	Factorvalue: fmt.Sprintf("%d", lowerValue),
					//	Timestamp:   now.UnixMilli(),
					//},
				}

				// 发送HTTP POST请求
				err = sendHttpRequest(requestData)
				if err != nil {
					log.Printf("Error sending HTTP request for server %s: %v", config.Address, err)
				}
			} else {
				fmt.Printf("Server %s - Machine ID %d: Upper value unchanged, skipping HTTP push (unchanged count: %d).\n", 
					config.Address, machineID, state.UnchangedCount)
			}
		} else {
			log.Printf("Server %s - Invalid data length: %d\n", config.Address, len(hexStr))
		}

		// 根据配置中的发送间隔等待
		interval, err := time.ParseDuration(config.SendInterval)
		if err != nil {
			log.Fatalf("Error parsing send interval for server %s: %v", config.Address, err)
		}
		time.Sleep(interval)
	}
}

// 将16进制字符串转换为10进制整数
func hexToDec(hexStr string) int64 {
	var dec int64
	fmt.Sscanf(hexStr, "%x", &dec)
	return dec
}

// 发送HTTP POST请求
func sendHttpRequest(data []HttpRequestData) error {
	jsonData, err := json.Marshal(data)
	if err != nil {
		return err
	}

	resp, err := http.Post("http://www.tjmes.top/yin/yin/yinWorkOrder/dadianSync", "application/json", bytes.NewBuffer(jsonData))
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return fmt.Errorf("HTTP request failed with status code: %d", resp.StatusCode)
	}

	fmt.Println("HTTP request sent successfully")
	return nil
}

// 检查整数是否在切片中
func containsInt(slice []int, val int) bool {
	for _, item := range slice {
		if item == int(val) {
			return true
		}
	}
	return false
}
